import type { Plugin, ProxyOptions, UserConfig } from 'vite'
import { findBaseUrlFromEnv, urlToProxyPath } from './utils'

interface IProxyConfig {
  /** @description  环境中的基础路径字段, */
  envBaseUrlFields?: string | string[]
  /** @description  需要代理的地址 */
  baseUrls?: string[]
}
export default function uniProxy({ envBaseUrlFields = 'BASE_URL', baseUrls = [] } = {} as IProxyConfig): Plugin {
  const virtualModuleId = 'virtual:mui-proxy-map'
  const resolvedVirtualModuleId = `\0${virtualModuleId}`

  const proxyMap: Record<string, string> = {}
  return {
    name: 'vite-plugin-uni-proxy',
    enforce: 'pre',
    resolveId(id) {
      if (id === virtualModuleId) {
        return resolvedVirtualModuleId
      }
    },
    config(config: UserConfig, { mode }) {
      // 必须已经注册过前置插件，或者自己外部传入需要代理地址
      if (!config?.define!.__MUI_ENV_CONFIG__ && baseUrls.length === 0) {
        console.log('vite-plugin-uni-proxy必须先注册vite-plugin-uni-boot插件之后使用')
        return
      }
      const proxy: Record<string, ProxyOptions> = {}
      if (baseUrls.length > 0) { // 外部单独传入情况下
        baseUrls.forEach((baseUrl) => {
          const proxyPath = urlToProxyPath(baseUrl)
          if (proxy[proxyPath]) return // 相同地址不需要重复代理
          proxyMap[baseUrl] = proxyPath

          proxy[`/${proxyPath}`] = createProxyList(baseUrl, proxyPath)
        })
      }
      if (mode !== 'production') { // 根据环境变量自动获取到的代理地址
        if (!config.define?.__MUI_ENV_CONFIG__) return
        const envMap = JSON.parse(config.define.__MUI_ENV_CONFIG__)
        delete envMap.common

        Object.keys(envMap).forEach((envName) => {
          if (!envMap[envName]) return

          const baseUrls = findBaseUrlFromEnv(envMap[envName], envBaseUrlFields)
          if (baseUrls.length === 0) return

          baseUrls.forEach((baseUrl) => {
            const proxyPath = urlToProxyPath(baseUrl)
            if (proxy[proxyPath]) return // 相同地址不需要重复代理
            proxyMap[baseUrl] = proxyPath

            proxy[`/${proxyPath}`] = createProxyList(baseUrl, proxyPath)
          })
        })
      }
      if (!config.server) config.server = {}
      if (config.server.proxy) {
        Object.assign(config.server.proxy, proxy)
      }
      else {
        config.server.proxy = proxy as | Record<string, string | ProxyOptions> | undefined
      }
    },
    load(id) {
      if (id === resolvedVirtualModuleId) {
        return `export const proxyMap = ${JSON.stringify(proxyMap, null, 2)};`
      }
    },
  }
}

const httpsRE = /^https:\/\//
function createProxyList(baseUrl = '', proxyPath = '') {
  const isHttps = httpsRE.test(baseUrl)
  return {
    target: baseUrl, // 'https://192.168.1.2', //目标域名
    changeOrigin: true, // 需要代理跨域
    rewrite: (path: string) =>
      path.replace(new RegExp(`^/${proxyPath}`), ''), // 路径重写，把'/local_proxy'替换为''
    ...(isHttps ? { secure: true } : {})
    // bypass(req, res, options) {
    //   const proxyURL = options.target + options.rewrite(req.url)
    //   req.headers['x-req-proxyURL'] = proxyURL
    //   res.setHeader('x-req-proxyURL', proxyURL)
    // }
  }
}
